package com.icee.myth.console.channelHandler;

import com.icee.myth.common.protobufMessage.ProtobufMessageType;
import com.icee.myth.console.ServerMessageQueue;
import com.icee.myth.console.message.serverMessage.builder.ConsoleMessageBuilder;
import com.icee.myth.protobuf.ConsoleToManagerProtocol.ServerStatuses;
import com.icee.myth.protobuf.ExternalCommonProtocol.*;
import com.icee.myth.utils.LogConsts;
import com.icee.myth.utils.MLogger;
import com.icee.myth.utils.StackTraceUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufInputStream;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import java.io.IOException;

/**
 *
 * @author liuxianke
 */
public class ConsoleToManagerHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        // Add cluster channel connected message to message queue
        ServerMessageQueue.queue().offer(ConsoleMessageBuilder.buildManagerConnectMessage(ctx.channel()));
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        // Add cluster channel close message to message queue
        ServerMessageQueue.queue().offer(ConsoleMessageBuilder.buildManagerCloseMessage(ctx.channel()));
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        try {
            // add cluster channel received message to message queue
            ByteBuf byteBuf = (ByteBuf) msg;
            short type = byteBuf.readShort();
            int length = byteBuf.readInt();

            switch (type) {
                case ProtobufMessageType.MANAGER2CONSOLE_SERVER_START_OK: {
                    IntValueProto intValue = IntValueProto.getDefaultInstance().newBuilderForType().mergeFrom(new ByteBufInputStream(byteBuf)).build();
                    ServerMessageQueue.queue().offer(ConsoleMessageBuilder.buildServerStartOKMessage(intValue.getValue()));
                    break;
                }
                case ProtobufMessageType.MANAGER2CONSOLE_SERVER_SHUTDOWN_OK: {
                    IntValueProto intValue = IntValueProto.getDefaultInstance().newBuilderForType().mergeFrom(new ByteBufInputStream(byteBuf)).build();
                    ServerMessageQueue.queue().offer(ConsoleMessageBuilder.buildServerShutdownOKMessage(intValue.getValue()));
                    break;
                }
                case ProtobufMessageType.MANAGER2CONSOLE_SYNCCONFIG_RETURN: {
                    IntValueProto intValue = IntValueProto.getDefaultInstance().newBuilderForType().mergeFrom(new ByteBufInputStream(byteBuf)).build();
                    ServerMessageQueue.queue().offer(ConsoleMessageBuilder.buildSyncConfigReturnMessage(intValue.getValue()));
                    break;
                }
                case ProtobufMessageType.MANAGER2CONSOLE_GET_SERVER_STATUS_RETURN: {
                    ServerStatuses serverStatuses = ServerStatuses.getDefaultInstance().newBuilderForType().mergeFrom(new ByteBufInputStream(byteBuf)).build();
                    ServerMessageQueue.queue().offer(ConsoleMessageBuilder.buildGetServerStatusReturnMessage(serverStatuses));
                    break;
                }
                case ProtobufMessageType.MANAGER2CONSOLE_FORCE_SET_SERVER_SHUTDOWN_STATUS_OK: {
                    IntValueProto intValue = IntValueProto.getDefaultInstance().newBuilderForType().mergeFrom(new ByteBufInputStream(byteBuf)).build();
                    ServerMessageQueue.queue().offer(ConsoleMessageBuilder.buildForceSetServerShutdownStatusOKMessage(intValue.getValue()));
                    break;
                }
                case ProtobufMessageType.MANAGER2CONSOLE_FORCE_SET_SERVER_SHUTDOWN_STATUS_ERROR: {
                    IntValueProto intValue = IntValueProto.getDefaultInstance().newBuilderForType().mergeFrom(new ByteBufInputStream(byteBuf)).build();
                    ServerMessageQueue.queue().offer(ConsoleMessageBuilder.buildForceSetServerShutdownStatusErrorMessage(intValue.getValue()));
                    break;
                }
                case ProtobufMessageType.MANAGER2CONSOLE_LOAD_SERVER_CONFIG_OK: {
                    IntValueProto intValue = IntValueProto.getDefaultInstance().newBuilderForType().mergeFrom(new ByteBufInputStream(byteBuf)).build();
                    ServerMessageQueue.queue().offer(ConsoleMessageBuilder.buildLoadServerConfigOKMessage(intValue.getValue()));
                    break;
                }
                case ProtobufMessageType.MANAGER2CONSOLE_LOAD_SERVER_CONFIG_ERROR: {
                    VariableValueProto variableValue = VariableValueProto.getDefaultInstance().newBuilderForType().mergeFrom(new ByteBufInputStream(byteBuf)).build();
                    ServerMessageQueue.queue().offer(ConsoleMessageBuilder.buildLoadServerConfigErrorMessage(variableValue.getId(), (int)variableValue.getValue()));
                    break;
                }
                case ProtobufMessageType.MANAGER2CONSOLE_BATTLE_WIN_RATE_RESULT: {
                    IntValuesProto intValues = IntValuesProto.getDefaultInstance().newBuilderForType().mergeFrom(new ByteBufInputStream(byteBuf)).build();
                    ServerMessageQueue.queue().offer(ConsoleMessageBuilder.buildBattleWinRateResultMessage(intValues.getValues(0), intValues.getValues(1), intValues.getValues(2)));
                    break;
                }
                case ProtobufMessageType.MANAGER2CONSOLE_CARD_DRAW_RATE_RESULT: {
                    VariableValuesProto variableValuesProto = VariableValuesProto.getDefaultInstance().newBuilderForType().mergeFrom(new ByteBufInputStream(byteBuf)).build();
                    ServerMessageQueue.queue().offer(ConsoleMessageBuilder.buildCardDrawRateResultMessage(variableValuesProto));
                    break;
                }
                case ProtobufMessageType.MANAGER2CONSOLE_UNINIT_OCCUPY_INFO: {
                    IntValuesProto intValues = IntValuesProto.getDefaultInstance().newBuilderForType().mergeFrom(new ByteBufInputStream(byteBuf)).build();
                    ServerMessageQueue.queue().offer(ConsoleMessageBuilder.buildUninitOccupyInfoMessage(intValues));
                    break;
                }
                case ProtobufMessageType.MANAGER2CONSOLE_FIGHTING_OCCUPY_INFO: {
                    IntValuesProto intValues = IntValuesProto.getDefaultInstance().newBuilderForType().mergeFrom(new ByteBufInputStream(byteBuf)).build();
                    ServerMessageQueue.queue().offer(ConsoleMessageBuilder.buildFightingOccupyInfoMessage(intValues));
                    break;
                }
                case ProtobufMessageType.MANAGER2CONSOLE_DATE_TIME: {
                    LongValueProto longValueProto = LongValueProto.getDefaultInstance().newBuilderForType().mergeFrom(new ByteBufInputStream(byteBuf)).build();
                    ServerMessageQueue.queue().offer(ConsoleMessageBuilder.buildDateTimeMessage(longValueProto.getValue()));
                    break;
                }
                default:
                    System.out.println("unkown case");
                    break;
            }
        } catch (IOException ex) {
            MLogger.getlogger().log(LogConsts.LOGTYPE_NETERR, StackTraceUtil.getStackTrace(ex));
        }
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_DEBUG, StackTraceUtil.getStackTrace(cause));
//        MLogger.getlogger().log(LogConsts.LOGTYPE_NETERR, StackTraceUtil.getStackTrace(cause.getCause()));
        // TODO:关闭与Cluster的连接
//        ctx.channel().close();
    }

}
